package com.black.utils.commons.pool;

import com.alibaba.fastjson2.JSONObject;
import com.black.utils.config.loader.PropertiesLoader;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.regex.Pattern;

/**
 * @author ylx
 */
@Slf4j
public class PoolProperties {
    protected String sourcePath;
    protected Config config;
    protected final String IPV4_REGEX = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";

    public PoolProperties(String sourcePath) {
        this.sourcePath = sourcePath;
        loadConfig(sourcePath);
    }

    public void loadConfig(String sourcePath) {
        try {
            config = new PropertiesLoader().loadConfigObject(sourcePath, Config.class);
            validateConfig();
        } catch (IOException e) {
            log.error("Pool config file read failed", e);
            if (null == config) {
                throw new RuntimeException(e);
            }
        }
    }

    public void updateConfig() {
        loadConfig(sourcePath);
    }

    public void validateConfig() {
        if (null == config) {
            throw new IllegalStateException("Pool配置不能为空");
        }
        if (StringUtils.isBlank(config.ip)) {
            throw new IllegalStateException("服务器IP未配置");
        }
        if (!Pattern.matches(IPV4_REGEX, config.ip)) {
            try {
                InetAddress inetAddress = InetAddress.getByName(config.ip);
                if (null == inetAddress) {
                    throw new IllegalStateException("服务器IP地址或域名不合法");
                }
            } catch (UnknownHostException e) {
                throw new IllegalStateException("无法解析的域名或者IP");
            }
        }
        if (config.port <= 0 || config.port > 65535) {
            // 端口号需在0-65535之间
            throw new IllegalStateException("服务器端口配置不合法 需要【0，65535】");
        }
        if (StringUtils.isBlank(config.account)) {
            throw new IllegalStateException("服务器账号未配置");
        }
        if (StringUtils.isBlank(config.password)) {
            throw new IllegalStateException("服务器密码未配置");
        }
        if (StringUtils.isBlank(config.rootPath)) {
            throw new IllegalStateException("服务器根路径未配置");
        }
        if (config.maxCount <= 0) {
            log.warn("最大重试传输次数配置不合理，已默认设置为1");
            config.maxCount = 1;
        }
        if (config.timeout < 0) {
            log.warn("超时时间配置不合理，已默认设置为3秒");
            config.timeout = 3000;
        }
        log.info("配置加载成功 配置如下:");
        log.info(JSONObject.toJSONString(config));
    }

    public String getIp() {
        return config.ip;
    }

    public Integer getPort() {
        return config.port;
    }

    public String getAccount() {
        return config.account;
    }

    public String getPassword() {
        return config.password;
    }

    public String getRootPath() {
        return config.rootPath;
    }

    public Integer getMaxCount() {
        return config.maxCount;
    }

    public Integer getTimeout() {
        return config.timeout;
    }

    public String getEncoding() {
        return config.encoding;
    }

    public int getMinIdle() {
        return config.minIdle;
    }

    @Getter
    @Setter
    public static class Config {
        private String ip;

        private Integer port;

        private String account;

        private String password;

        private String rootPath;

        private Integer maxCount;

        private Integer timeout;

        private int minIdle = 5;

        private final String encoding = StandardCharsets.UTF_8.toString();
    }
}
